import { onUnmounted } from 'vue'
import { RouteLocationNormalized, RouteLocationRaw, useRouter } from 'vue-router'
import useVisitedRouteStore from '@/store/modules/visited-routes'
import bus from '@/utils/bus'

/**
 * 1. 关闭当前页 【新增底部关闭按钮】（关闭当前）
 * 返回当前左边的tab的页面
 * @function navigateClose
 *
 *
 * 2. 跳转新页面 【跳转到新增页面的方法】
 * 修改tab的title，并记录发起页面的router
 * @function navigateTo
 * @param {string} url - 目标页面的URL
 * @param {string} title - 新页面的标题
 *
 *
 * 3. 返回上一页 【新增页面的确认后关闭页面的方法】（关闭当前，并返回发起页，清空url参数）
 * 和navigateTo 组合使用，不要单独使用，返回发起页面
 * 会使发起页面重新加载（刷新数据）
 * @function navigateBack
 *
 *
 * 4. 重定向跳转到指定页面(强制重新加载)
 * @function redirectTo
 * @param {string} url - 目标页面的URL
 *
 *
 * 5. list热更新
 * 需要用navigateTo记录发起页面的name，通知时候，通过name找到对应的页面，并触发
 * 注册热更新
 * @function registerListHotUpdate
 * 跳转到新增页面，navigateBack 会自动强制刷新
 * @function navigateToCreate
 */

// 支持list热更新的页面注册表
const listHotUpdate_registry = new Map()
const useNavigate = () => {
  const router = useRouter()
  const visitedRouteStore = useVisitedRouteStore()

  function navigateClose() {
    const currentRoute = router.currentRoute.value
    const fullPath = currentRoute.fullPath
    const visitedRoutes = visitedRouteStore.getVisitedRoutes
    // 当前index
    const findItemIndex = visitedRoutes.findIndex((it) => it.fullPath === fullPath)
    if (findItemIndex != -1) {
      visitedRouteStore.closeItemVisitedView(fullPath)
      const lastTab = visitedRoutes[findItemIndex - 1]
      if (lastTab) {
        router.replace(lastTab.fullPath)
      }
    }
  }

  function navigateBack(forceRefresh = false) {
    const currentRoute = router.currentRoute.value
    const visitedRoutes = visitedRouteStore.getVisitedRoutes
    const currentTab = visitedRoutes.find((it: RouteLocationNormalized) => it.fullPath == currentRoute.fullPath)
    if (!currentTab || !currentTab.meta?.originator) {
      navigateClose()
      return
    }
    // 删除访问tab
    visitedRouteStore.closeItemVisitedView(currentRoute.fullPath)
    const originator = currentTab.meta.originator as OriginatorRouter
    const backPath = originator.fullPath
    const backName = originator.name
    const eventName = listHotUpdate_registry.get(backName)
    const backForceRefresh = originator.forceRefresh
    // 强制刷新，forceRefresh=true 或者 backForceRefresh=true 或者 返回列表不支持热更新
    const shouldForceRefresh = forceRefresh || !eventName || backForceRefresh
    // 强制更新
    if (shouldForceRefresh) {
      console.log('🐳 >热更新>强制更新：', eventName)
      router.push({ path: '/redirect' + backPath })
      return
    }
    // 通知热更新
    router.replace(backPath) // 跳转路由
    if (eventName) {
      console.log('🐳 >热更新>触发热更新：', eventName)
      bus.emit(eventName)
    }
  }

  // 2.路由跳转 navigateTo，新开一个操作页面并修改 title
  function navigateTo(to: RouteLocationRaw, title = '', forceRefresh = false) {
    const currentRoute = router.currentRoute.value
    // 记录发起页面信息
    visitedRouteStore.originator = {
      name: currentRoute.name, // 热更新
      path: currentRoute.path,
      fullPath: currentRoute.fullPath,
      title,
      forceRefresh,
    }
    router.push(to)
  }
  // 跳转到新增页面
  function navigateToCreate(to: RouteLocationRaw, title = '') {
    navigateTo(to, title, true)
  }

  // 3.路由跳转 replaceTo，区别 navigateTo 的是，记录的页面信息是当前页 meta 中的信息
  function replaceTo(to: RouteLocationRaw, title = '', method = 'push') {
    const currentRoute = router.currentRoute.value
    const currentOriginator: any = currentRoute.meta.originator

    // 记录当前页面信息
    visitedRouteStore.originator = {
      path: currentOriginator.path,
      fullPath: currentOriginator.fullPath,
      title,
    }
    if (method == 'replace') {
      router.replace(to)
    } else {
      router.push(to)
    }
  }

  // 重定向路由 redirectTo o_url原始的url
  function redirectTo(o_url: String) {
    router.push('/redirect' + o_url)
  }

  // 注册list热更新
  // 返回上一页并加载数据（不重载页面）
  function registerListHotUpdate(loadFn: Function) {
    const hotUpdate_routerName = router.currentRoute.value.name as string
    const eventName = 'ListHotUpdate.' + hotUpdate_routerName
    listHotUpdate_registry.set(hotUpdate_routerName, eventName)
    console.log('🐳 >热更新>列表注册：', router.currentRoute.value.meta.title, listHotUpdate_registry)
    // 共用这个bus的name，需要区分页面
    // 通过routerName区分
    // 需要热更新的list的routerName，注册navigateBack2LoadData的list
    bus.on(eventName, () => {
      console.log('🐳 >热更新>接收热更新', eventName)
      loadFn()
    })
    onUnmounted(() => {
      bus.off(eventName)
    })
  }

  return {
    navigateClose,
    navigateBack,
    navigateTo,
    redirectTo,
    replaceTo,
    registerListHotUpdate,
    navigateToCreate,
  }
}

export default useNavigate

type OriginatorRouter = {
  name: string
  path: string
  fullPath: string
  title: string
  forceRefresh: boolean
}
